home *** CD-ROM | disk | FTP | other *** search
/ Aminet 30 / Aminet 30 (1999)(Schatztruhe)[!][Apr 1999].iso / Aminet / dev / cross / GBDK-2.0.lha / GBDK / lib / scanf.c < prev    next >
C/C++ Source or Header  |  1998-10-01  |  2KB  |  152 lines

  1. #include <stdio.h>
  2. #include <stdarg.h>
  3.  
  4. static UBYTE scan_skip(char *s, UBYTE i)
  5. {
  6. oncemore:
  7.   while(isspace(s[i]))
  8.     i++;
  9.   if(s[i] == 0) {
  10.     gets(s);
  11.     i = 0;
  12.     goto oncemore;
  13.   }
  14.   return i;
  15. }
  16.  
  17. static UBYTE scan_int(char *s, UBYTE i, UBYTE base, BYTE *nb)
  18. {
  19.   BYTE n = 0;
  20.   UBYTE j, sign = 0;
  21.  
  22.   switch(s[i])
  23.     {
  24.     case '-':
  25.       sign++;
  26.       /* and fall through */
  27.     case '+':
  28.       ++i;
  29.       break;
  30.     }
  31.   while(1) {
  32.     if(isdigit(s[i]))
  33.       j = s[i] - '0';
  34.     else if(isalpha(s[i]))
  35.       j = toupper(s[i]) - 'A' + 10;
  36.     else
  37.       break;
  38.     if(j >= base)
  39.       break;
  40.     n = base * n + j;
  41.     i++;
  42.   }
  43.   *nb = (sign == 0 ? n : -n);
  44.   return i;
  45. }
  46.  
  47. static UBYTE scan_long(char *s, UBYTE i, UBYTE base, WORD *nb)
  48. {
  49.   WORD n = 0;
  50.   UBYTE j, sign = 0;
  51.  
  52.   switch(s[i])
  53.     {
  54.     case '-':
  55.       sign++;
  56.       /* and fall through */
  57.     case '+':
  58.       ++i;
  59.       break;
  60.     }
  61.   while(1) {
  62.     if(isdigit(s[i]))
  63.       j = s[i] - '0';
  64.     else if(isalpha(s[i]))
  65.       j = toupper(s[i]) - 'A' + 10;
  66.     else
  67.       break;
  68.     if(j >= base)
  69.       break;
  70.     n = base * n + j;
  71.     i++;
  72.   }
  73.   *nb = (sign == 0 ? n : -n);
  74.   return i;
  75. }
  76.  
  77. BYTE scanf(char *fmt, ...)
  78. {
  79.   va_list ap;
  80.   char s[64];
  81.   UBYTE i = 0;
  82.   BYTE nb = 0;
  83.  
  84.   gets(s);
  85.   va_start(ap, fmt);
  86.   for(; *fmt; fmt++) {
  87.     if(isspace(*fmt))
  88.       continue;
  89.     i = scan_skip(s, i);
  90.     if(*fmt == '%') {
  91.       switch(*++fmt) {
  92.       case 'c':
  93.     /* char */
  94.     *va_arg(ap, char *) = s[i++];
  95.     break;
  96.       case 'd':
  97.     /* decimal int */
  98.       case 'u':
  99.     /* unsigned int */
  100.     i = scan_int(s, i, 10, va_arg(ap, BYTE *));
  101.     break;
  102.       case 'o':
  103.     /* octal int */
  104.     i = scan_int(s, i, 8, va_arg(ap, BYTE *));
  105.     break;
  106.       case 'x':
  107.     /* hexadecimal int */
  108.     i = scan_int(s, i, 16, va_arg(ap, BYTE *));
  109.     break;
  110.       case 's':
  111.     /* string */
  112.     {
  113.       BYTE j = 0;
  114.       char *d = va_arg(ap, char *);
  115.       while((d[j++] = s[i++]) != 0)
  116.         ;
  117.     }
  118.       break;
  119.       case 'l':
  120.     /* long */
  121.     switch(*++fmt) {
  122.     case 'd':
  123.       /* decimal long */
  124.     case 'u':
  125.       /* unsigned long */
  126.       i = scan_long(s, i, 10, va_arg(ap, WORD *));
  127.       break;
  128.     case 'o':
  129.       /* octal long */
  130.       i = scan_long(s, i, 8, va_arg(ap, WORD *));
  131.       break;
  132.     case 'x':
  133.       /* hexadecimal long */
  134.       i = scan_long(s, i, 16, va_arg(ap, WORD *));
  135.       break;
  136.     }
  137.     break;
  138.       default:
  139.     if(s[i] != *fmt)
  140.       return -1;
  141.     break;
  142.       }
  143.       nb++;
  144.     } else
  145.       if(s[i] != *fmt)
  146.     return -1;
  147.   }
  148.   va_end(ap);
  149.  
  150.   return nb;
  151. }
  152.